package com.woniuxy.controller;

import com.woniuxy.entity.*;
import com.woniuxy.realm.CustomizedToken;
import com.woniuxy.realm.LoginType;
import com.woniuxy.service.*;
import com.woniuxy.utils.LoginRegister;
import com.woniuxy.utils.PhoneCode;
import com.woniuxy.utils.RegexUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.SessionScope;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 用户登录注册等功能
 * 以下所有功能原厂制造
 * @Author:吴毛伟
 */
@Controller
@RequestMapping("/user")
public class UserController{
    @Autowired
    private UserService userService;
    @Autowired
    private CoachService coachService;
    @Autowired
    private VenueService venueService;
    @Autowired
    private DynamicService dynamicService;
    @Autowired
    private MessageService messageService;

    private static final String USER_LOGIN_TYPE= LoginType.USER.toString();

    /**
     * 通过手机号登录
     * @param user
     * @param recode
     * @return
     */
    @RequestMapping("/loginByPhoneNum")
    @ResponseBody
    public ResponseEntity loginByPhoneNum(User user,String recode,HttpServletRequest request){
        System.out.println(user.getPhoneNumber()+recode);
            HttpSession session=request.getSession();
            // 获取随机验证码
            String code= (String) session.getAttribute("code");
            //判断验证码是否正确
            if (!code.equals(recode)||recode.trim().equals("")){
                return  ResponseEntity.ERROR.setCode(306).setMsg("验证码错误，请重新输入!");
            }
            //如果返回值为1则登录成功
        int error=userService.loginByPhoneNum(user);
           if (error==1){
               //通过账号查询一次账户信息
               User users=userService.selectUserByPhoneNumber(user.getPhoneNumber());
               session.setAttribute("user",users);
               return  ResponseEntity.SUCCESS.setMsg("");
           }else {
               //反之返回错误编码信息
               return  ResponseEntity.ERROR;
           }
    }

    /**
     * 通过账号登录
     * @param user
     * @return
     */
    @RequestMapping("/loginByUname")
    @ResponseBody
    public ResponseEntity loginByUname(User user,HttpServletRequest request,@RequestParam(value = "rm", defaultValue = "false") boolean rm) {
        HttpSession sessions = request.getSession();
        // 1.获取主题对象，subject 当前用户 对应一个客户端程序
        Subject currentUser = SecurityUtils.getSubject();
        // 获取shiro的session
        Session session = currentUser.getSession();
        //当用户不为空时
        if (!currentUser.isAuthenticated()) {
            if (!RegexUtils.passwordIsRight(user.getPwd())) {
                //判断用户名是否正确不正确返回306代表账号错误
                return ResponseEntity.ERROR.setCode(307).setMsg("密码错误应输入6-12位数字密码");
            }
            // 没认证过
            // 将账号密码信息封装成token，方便后面认证的操作
            String pwd = new SimpleHash("MD5", user.getPwd(), user.getUname(), 1024).toString();
            System.out.println(pwd+"--------------------------");
            CustomizedToken customizedToken = new CustomizedToken(user.getUname(), pwd, USER_LOGIN_TYPE);
            // 判断用户是否勾选
            if (rm) {
                //开启记住我的功能
                customizedToken.setRememberMe(true);
            }
            // 当前“用户”拿着令牌去安全管理器中进行身份的认证，会将令牌交给securitymanager进行认证
            try {
                currentUser.login(customizedToken);
                User users = userService.loginByUname(user);
                session.setAttribute("user", users);
                System.out.println("认证成功");
                return ResponseEntity.SUCCESS;
                // 不报任何异常，表示账号不存在
            } catch (UnknownAccountException e) {
                // 账号不存在 info为空
                System.out.println("账号不存在");
                return ResponseEntity.ERROR.setCode(4);
            } catch (IncorrectCredentialsException e) {
                // 密码错误
                System.out.println("密码错误");
                return ResponseEntity.ERROR.setCode(3);
            } catch (AuthenticationException e) {
                // 其他异常
                return ResponseEntity.ERROR.setCode(500);
            }
        }
        return ResponseEntity.ERROR;
    }
/**
 * 通过登录信息查询自己的信息
 */
@RequestMapping("/selectMyByUid")
@ResponseBody
public ResponseEntity<User> selectMyByUid(HttpServletRequest request){
    //获取当前用户的id
    HttpSession session=request.getSession();
    User user=(User)session.getAttribute("user");
    //通过账号获取uid
    int uid=user.getUid();
    ResponseEntity<User> entity = new ResponseEntity<User>();
    User users=userService.selectUserById(uid);
    entity.setCode(200);
    entity.setMsg("OK");
    entity.setData(users);
    return entity;
}
    /**
     *
     * @param phoneNumber
     * @param request
     * @return
     */
    @RequestMapping("/sendCode")
    @ResponseBody
    public ResponseEntity sendCode(String phoneNumber,HttpServletRequest request){
        //判断传入的手机号是否正确
        if (!RegexUtils.telphoneIsRight(phoneNumber)){
            //如果手机号不正确则返回300 为手机号错误
            return ResponseEntity.ERROR.setCode(305).setMsg("手机号错误!");
        }
        /*System.out.println(session.getAttribute("code"));*/
        //如果返回值为5则登录成功
        int error=userService.selectByPhone(phoneNumber);
        if (error==5){
            PhoneCode phoneCode = new PhoneCode();
            // 获取随机验证码
            String code = phoneCode.getCode();
            // 接收短信的手机号
            String phone = phoneNumber;
            // 调用发短信的方法
            phoneCode.sendCode(phone, code);
            HttpSession session=request.getSession();
            session.setAttribute("code",code);
            return ResponseEntity.SUCCESS.setMsg("");
        }else {
            //反之返回错误编码信息
            return ResponseEntity.ERROR.setCode(error);
        }
    }

    /**
     * 注册;
     * @return
     */
    @RequestMapping("/register")
    @ResponseBody
    public ResponseEntity register(User user){
        if (!RegexUtils.accountIsRight(user.getUname())){
            //判断用户名是否正确不正确返回306代表账号错误
            return ResponseEntity.ERROR.setCode(306).setMsg("账号不规范应该输入2-10位包含字母数字的账号");
        }
        if (!RegexUtils.telphoneIsRight(user.getPhoneNumber())){
            //判断手机号是否正确 不正确 返回305代表手机号错误
            return ResponseEntity.ERROR.setCode(305).setMsg("手机号错误!");
        }
        if (!RegexUtils.passwordIsRight(user.getPwd())){
            //判断用户名是否正确不正确返回306代表账号错误
            return ResponseEntity.ERROR.setCode(307).setMsg("密码错误应输入6-12位数字密码");
        }
//        String pwd = new SimpleHash("MD5", user.getPwd(), user.getUname(), 1024).toString();
//        user.setPwd(pwd);
        int error=userService.register(user);
        if (error==2){
            //注册成功
            return ResponseEntity.SUCCESS.setMsg("");
        }else {
            //反之返回错误编码信息
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 查询所有被当前用户关注的好友
     * 分页查询
     */
    @RequestMapping("/selectRelationship")
    @ResponseBody
    public ResponseEntity<PageBean<Relationship>> selectRelationship(String p,HttpServletRequest request){
        int page = 1;
        System.out.println(p+"----------------------------------------");
        if (p != null) {
            page = Integer.parseInt(p);
        }
        //获取当前用户的id
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        ResponseEntity<PageBean<Relationship>> entity = new ResponseEntity<PageBean<Relationship>>();
        //通过账号获取uid
        int uid=user.getUid();
        PageBean<Relationship> relationship = userService.getByPage(page, uid);
        entity.setCode(200);
        entity.setMsg("OK");
        entity.setData(relationship);
        return entity;
    }
    /**
     * 添加关注信息
     */
    @RequestMapping("/insertRelationship")
    @ResponseBody
    public ResponseEntity insertRelationship(int id,HttpServletRequest request){
    Relationship relationship=new Relationship();
        //获取当前登录用户的id
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        //测试数据 先定一个userid=10000001
        relationship.setFan(user.getUid());
     //通过id查询判断被关注者的信息
        if (id>=10000000){
            int uid=id;
            //则去用户表查询被关注者的用户信息
            User users=userService.findUserByUid(uid);
            relationship.setFollowed(uid);
            relationship.setAvatar(users.getAvatar());
            relationship.setNickname(users.getNickname());
        }else if (id>=100000&&id<10000000){
            int cid=id;
            //则去教练表查询教练信息
            Coach coach=coachService.findCoachByCid(cid);
            relationship.setFollowed(cid);
            relationship.setAvatar(coach.getAvatar());
            relationship.setNickname(coach.getNickname());
        }else{
            int vid=id;
            //去场馆查询场馆信息
           Venue venue=venueService.findVenueByVenueId(vid);
            relationship.setFollowed(vid);
            relationship.setAvatar(venue.getImage1());
            relationship.setNickname(venue.getNickname());
        }
        //添加信息
        int error=userService.insertRelationship(relationship);
        if (error==1){
            //添加好友成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 查询所有用户
     */
    @RequestMapping("/selectAllUser")
    @ResponseBody
    public ResponseEntity<List<User>> selectAllUser(){
        ResponseEntity<List<User>> entity = new ResponseEntity<List<User>>();
        List<User> users=userService.selectAllUser();
        entity.setCode(200);
        entity.setMsg("OK");
        entity.setData(users);
        return entity;
    }
    /**
     * 查看被我关注的用户信息
     */
   @RequestMapping("/selectUserById")
    @ResponseBody
    public ResponseEntity<User> selectUserById(int uid){
       ResponseEntity<User> entity = new ResponseEntity<User>();
       User users=userService.selectUserById(uid);
        entity.setCode(200);
        entity.setMsg("OK");
        entity.setData(users);
        return entity;
    }
    /**
     * 查看所有的通知信息
     */
    @RequestMapping("/selectMessageByUid")
    @ResponseBody
    public ResponseEntity<List<Message>> selectMessageByUid(HttpServletRequest request){
        ResponseEntity<List<Message>> entity = new ResponseEntity<List<Message>>();
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        int uid=user.getUid();
        List<Message> messages=userService.selectMessageByUid(uid);
        entity.setCode(200);
        entity.setMsg("OK");
        entity.setData(messages);
        return entity;
    }
    /**
     * 完善用户信息步骤
     * 1.更改绑定手机号
     */
    @RequestMapping("/updatePhoneNumberByUid")
    @ResponseBody
    public ResponseEntity updatePhoneNumberByUid(String phoneNumber,HttpServletRequest request){
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        /*int uid=user.getUid();*/
        int uid=user.getUid();
        //判断传入的手机号是否正确
        if (!RegexUtils.telphoneIsRight(phoneNumber)){
            //如果手机号不正确则返回300 为手机号错误
            return  ResponseEntity.ERROR.setCode(305);
        }
        //修改信息
        int error=userService.updatePhoneNumberByUid(phoneNumber,uid);
        if (error==1){
            //修改成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 2.修改信息是否公开
     */
    @RequestMapping("/updateisOpenByUid")
    @ResponseBody
    public ResponseEntity updateisOpenByUid(String isOpen,HttpServletRequest request){
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        /*int uid=user.getUid();*/
        int uid=user.getUid();
        //修改信息
        int error=userService.updateisOpenByUid(uid,isOpen);
        if (error==1){
            //修改成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 3.修改头像
     */
    @RequestMapping("/updateAvatarByUid")
    @ResponseBody
    public ResponseEntity updateAvatarByUid(MultipartFile file, HttpServletRequest request) throws IOException {
        System.out.println(file.getOriginalFilename()+"-------------------------------");
        //获取图片名字
        String filename=file.getOriginalFilename();
        int index = filename.lastIndexOf(".");
        String type = filename.substring(index);
        //给图片命名
        String filenames = UUID.randomUUID().toString() + type;
        // 得到存放文件的目录
        String path = request.getServletContext().getRealPath("");// 当前项目的根路径
        File root = new File(path);
        File main= root.getParentFile();
        File fileDir = new File(main, "resources/static/images");
        /*System.out.println(fileDir+"++++++++++++++++++++++++++++++++++++++++");*/
        if (!fileDir.exists()) {
            fileDir.mkdirs(); // 创建
        }
        // 得到文件存储的路径 files/文件名
        filename = fileDir.getAbsolutePath() + File.separator + filenames;
       /* System.out.println(filename+"**************************************");*/
        File destFile = new File(filename);
        try {
            file.transferTo(destFile);// 写入磁盘
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        int uid=user.getUid();
        //上传图片信息到数据库
        String avatar="../../images/"+filenames;
        int error=userService.updateAvatarByUid(avatar,uid);
        if (error==1){
            //修改成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 4.修改昵称
     */
    @RequestMapping("/updateNickNameByUid")
    @ResponseBody
    public ResponseEntity updateNickNameByUid(String nickname,HttpServletRequest request){
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        /*int uid=user.getUid();*/
        int uid=user.getUid();
        //修改信息
        int error=userService.updateNickNameByUid(nickname,uid);
        if (error==1){
            //修改成功
            return ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 5.添加QQ号
     */
    @RequestMapping("/updateQQByUid")
    @ResponseBody
    public ResponseEntity updateQQByUid(String qq,HttpServletRequest request){
        //判断QQ是否符合规格
        String regex="[1-9]\\d{3,11}";
        if (!qq.matches(regex)||qq.trim().equals("")){
            //qq输入错误，请重新输入
            return ResponseEntity.ERROR.setCode(308);
        }
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        /*int uid=user.getUid();*/
        int uid=user.getUid();
        //修改qq信息
        int error=userService.updateQQByUid(qq,uid);
        /*System.out.println(error);*/
        if (error==1){
            //修改成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 6.添加地址
     */
    //添加地址
    @RequestMapping("/insertAddressByUid")
    @ResponseBody
    public ResponseEntity insertAddressByUid(String address,BigDecimal longitude, BigDecimal latitude,HttpServletRequest request){
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        System.out.println(longitude);
        /*int uid=user.getUid();*/
        int uid=user.getUid();
        //修改qq信息
        int error=userService.insertAddressByUid(address,uid,longitude,latitude);
        if (error==1){
            //修改成功
            return  ResponseEntity.SUCCESS;
        }else {
            return ResponseEntity.ERROR.setCode(error);
        }
    }
    /**
     * 通过手机号修改密码
     */
    @RequestMapping("/updatePwdByPhoneNumber")
    @ResponseBody
    public ResponseEntity updatePwdByPhoneNumber(User user,String repass,HttpServletRequest request){
        HttpSession session=request.getSession();
        User users=(User)session.getAttribute("user");
        /*System.out.println(user.getPhoneNumber()+"------"+user.getPwd()+"-------"+repass+"---------------");*/
        //判断传入的手机号是否正确
        if (!RegexUtils.telphoneIsRight(user.getPhoneNumber())){
            //如果手机号不正确则返回305 为手机号错误
            return ResponseEntity.ERROR.setCode(305);
        }
        if (!RegexUtils.passwordIsRight(user.getPwd())||!RegexUtils.passwordIsRight(repass)){
            return ResponseEntity.ERROR.setCode(307);
        }
        /*int uid=users.getUid();*/
        int uid=user.getUid();
        //修改qq信息
        int error=userService.updatePwdByPhoneNumber(uid,user.getPwd(),user.getPhoneNumber(),repass);
        if (error==1){
            //修改成功
            return ResponseEntity.SUCCESS.setMsg("");
        }else {
            return ResponseEntity.ERROR.setCode(error).setMsg("");
        }
    }
    /**
     * 朋友圈
     */
    @RequestMapping("/findMyFriendsDynamic")
    @ResponseBody
    public ResponseEntity<List<Dynamic>> findMyFriendsDynamic(HttpServletRequest request) {
        // 查询所有好友
        HttpSession session=request.getSession();
        User user=(User)session.getAttribute("user");
        int uid=user.getUid();
        // 假设查出好友
        List<Relationship> relationships =userService.selectRelationship(uid);
        // 遍历查询好友动态
        List<Dynamic> dy = new ArrayList<>();
        for (int i = 0; i < relationships.size(); i++) {
            int sender = relationships.get(i).getFollowed();
            List<Dynamic> temp = dynamicService.findDynamicBySender(sender);
            dy.addAll(temp);
        }
        ResponseEntity<List<Dynamic>> entity = new ResponseEntity<List<Dynamic>>(dy);
        return entity;
    }
    /**
     * 根据mid修改message已读状态
     */
    @RequestMapping("/updateMessageByMid")
    @ResponseBody
    public ResponseEntity updateMessageByMid(int mid){
        int error=messageService.changeMessageStatus(mid);
        if (error==1){
            //修改成功
            return ResponseEntity.SUCCESS.setMsg("");
        }else {
            return ResponseEntity.ERROR.setCode(300).setMsg("");
        }
    }
    @RequestMapping("/uploads")
    @ResponseBody
    public void uploads(HttpServletRequest request){
        String path = request.getServletContext().getRealPath("");// 当前项目的根路径
        File root = new File(path);
        File main= root.getParentFile();
        File fileDir = new File(main, "resources/static");
        System.out.println(fileDir+"++++++++++++++++++++++++++++++++++++++++");
    }
}
